<template>
	<div class="page-container">
		<!-- 固定在顶部的区域 -->
		<div class="fixed-top">
			<van-field v-model="name" label="请输入签名:" placeholder="请输入签名" input-align="right" :readonly="isDrawing"
				@paste.stop @copy.stop />

			<van-row>
				<van-col span="8">
					<van-button type="primary" @click="generateMizige">生成米字格</van-button>
				</van-col>
				<van-col span="8">
					<van-button type="info" @click="clearSignature">清除签名</van-button>
				</van-col>
				<van-col span="8">
					<van-button type="success" @click="exportAsImage">导出为图片</van-button>
				</van-col>
			</van-row>
		</div>

		<!-- 可滚动的签名区域 -->
		<div class="scrollable-signature" :style="{ overflowY: isDrawing ? 'hidden' : 'auto' }">
			<div id="mizigeContainer">
				<div v-for="(item, index) in mizigeCount" :key="index" class="mizige">
					<!-- 添加canvas容器用于事件拦截 -->
					<div class="canvas-wrapper" @touchstart="handleCanvasTouchStart(index, $event)"
						@mousedown="handleCanvasTouchStart(index, $event)">
						<canvas type="2d" :id="`canvas-${index}`" :width="mizigeSize" :height="mizigeSize"
							@touchmove="draw(index, $event)" @touchend="stopDrawing(index)"
							@touchcancel="stopDrawing(index)" @mousemove="draw(index, $event)"
							@mouseup="stopDrawing(index)" @mouseout="stopDrawing(index)"
							@touchmove.stop="handleTouchMove"></canvas>
					</div>
				</div>
			</div>
		</div>

		<canvas id="combinedCanvas" class="hidden-canvas" type="2d"></canvas>
	</div>
</template>

<script>
	export default {
		data() {
			return {
				name: '罗纳耳朵加字',
				mizigeCount: 0,
				mizigeSize: 100,
				isDrawing: false,
				currentCanvasIndex: -1, // 当前正在绘制的canvas索引
				drawingContexts: [],
				canvasElements: [],
				canvasRects: [], // 存储每个canvas的位置信息
				lastX: 0,
				lastY: 0,
				scaleFactor: 1,
				pixelRatio: 1,
				// 新增：存储隐藏合并canvas的实例 （避免重复查询DOM）
				combinedCanvas: null,
				combinedCtx: null
			};
		},
		onReady() {
			// 页面就绪时，提前获取隐藏合并canvas的实例和上下文
			this.initCombinedCanvas();
			uni.getSystemInfo({
				success: (res) => {
					this.pixelRatio = res.pixelRatio;
				}
			});
			this.generateMizige();
		},
		methods: {
			// 新增：初始化隐藏的合并专用canvas
			initCombinedCanvas() {
				const query = uni.createSelectorQuery().in(this);
				query.select('#combinedCanvas').fields({
					node: true,
					size: true
				}).exec((res) => {
					if (!res[0] || !res[0].node) {
						uni.showToast({
							title: '合并画布初始化失败',
							icon: 'none'
						});
						return;
					}
					// 保存合并canvas的实例和上下文
					this.combinedCanvas = res[0].node;
					this.combinedCtx = this.combinedCanvas.getContext('2d');
				});
			},
			// 处理canvas容器的触摸开始事件（用于边界检测）
			handleCanvasTouchStart(index, event) {
				// 获取当前canvas的位置信息
				const query = uni.createSelectorQuery().in(this);
				query.select(`#canvas-${index}`).boundingClientRect().exec((res) => {
					if (res[0]) {
						this.canvasRects[index] = res[0];
						// 检查触摸点是否在canvas内部
						const touch = event.touches ? event.touches[0] : event.changedTouches ? event
							.changedTouches[0] : event;
						if (this.isPointInCanvas(touch, res[0])) {
							this.currentCanvasIndex = index;
							this.startDrawing(index, event);
						} else {
							// 不在canvas内则不开始绘制
							this.isDrawing = false;
							this.currentCanvasIndex = -1;
						}
					}
				});
			},

			// 检查点是否在canvas内部
			isPointInCanvas(point, rect) {
				return (
					point.clientX >= rect.left &&
					point.clientX <= rect.right &&
					point.clientY >= rect.top &&
					point.clientY <= rect.bottom
				);
			},

			handleTouchMove(event) {
				// 如果正在绘制且有当前激活的canvas
				if (this.isDrawing && this.currentCanvasIndex !== -1) {
					// 检查触摸点是否仍在当前canvas内
					const rect = this.canvasRects[this.currentCanvasIndex];
					const touch = event.touches ? event.touches[0] : event.changedTouches ? event.changedTouches[0] :
						event;

					if (!rect || !this.isPointInCanvas(touch, rect)) {
						// 如果移出canvas则停止绘制
						this.stopDrawing(this.currentCanvasIndex);
						this.currentCanvasIndex = -1;
					}

					event.stopPropagation();
					return false;
				}
				return true;
			},

			drawMizige(ctx) {
				ctx.clearRect(0, 0, this.mizigeSize, this.mizigeSize);
				ctx.beginPath();
				ctx.rect(0, 0, this.mizigeSize, this.mizigeSize);
				ctx.strokeStyle = 'red';
				ctx.lineWidth = 2;
				ctx.stroke();
				ctx.beginPath();
				ctx.moveTo(0, 0);
				ctx.lineTo(this.mizigeSize, this.mizigeSize);
				ctx.strokeStyle = 'red';
				ctx.lineWidth = 2;
				ctx.stroke();
				ctx.beginPath();
				ctx.moveTo(0, this.mizigeSize);
				ctx.lineTo(this.mizigeSize, 0);
				ctx.strokeStyle = 'red';
				ctx.lineWidth = 2;
				ctx.stroke();
				ctx.beginPath();
				ctx.moveTo(0, this.mizigeSize / 2);
				ctx.lineTo(this.mizigeSize, this.mizigeSize / 2);
				ctx.strokeStyle = 'red';
				ctx.lineWidth = 2;
				ctx.stroke();
				ctx.beginPath();
				ctx.moveTo(this.mizigeSize / 2, 0);
				ctx.lineTo(this.mizigeSize / 2, this.mizigeSize);
				ctx.strokeStyle = 'red';
				ctx.lineWidth = 2;
				ctx.stroke();
				ctx.setLineDash([]);
			},

			generateMizige() {
				this.mizigeCount = this.name.length;
				this.drawingContexts = [];
				this.canvasElements = [];
				this.canvasRects = [];

				setTimeout(() => {
					for (let i = 0; i < this.mizigeCount; i++) {
						const query = uni.createSelectorQuery().in(this);
						query.select(`#canvas-${i}`).fields({
							node: true,
							size: true
						}).exec((res) => {
							if (!res[0]) return;

							const canvas = res[0].node;
							this.canvasElements[i] = canvas;

							// 获取canvas位置信息
							const rectQuery = uni.createSelectorQuery().in(this);
							rectQuery.select(`#canvas-${i}`).boundingClientRect().exec((rectRes) => {
								if (rectRes[0]) {
									this.canvasRects[i] = rectRes[0];
								}
							});

							canvas.width = res[0].width * this.pixelRatio;
							canvas.height = res[0].height * this.pixelRatio;
							const ctx = canvas.getContext('2d');
							ctx.scale(this.pixelRatio, this.pixelRatio);

							this.drawingContexts.push(ctx);
							this.drawMizige(ctx);
							this.drawTextMethod(ctx, i)
						});
					}
				}, 50);
			},
			// 绘制空心文字轨迹
			drawTextMethod(ctx, i) {
				if (this.name.length > i) {
					const text = this.name.charAt(i);
					const fontSize = Math.min(this.mizigeSize * 0.8, 80);
					ctx.font = `${fontSize}px SimSun`;
					ctx.strokeStyle = 'red';
					ctx.lineWidth = 1;
					const textWidth = ctx.measureText(text).width;
					const textHeight = fontSize;
					const x = (this.mizigeSize - textWidth) / 2;
					const y = (this.mizigeSize + textHeight) / 2;
					ctx.strokeText(text, x, y);
				}
			},
			startDrawing(index, event) {
				this.isDrawing = true;

				const touch = event.touches ? event.touches[0] : event.changedTouches ? event.changedTouches[0] : event;
				const rect = this.canvasRects[index];

				if (!rect) return;

				const offsetX = touch.clientX - rect.left;
				const offsetY = touch.clientY - rect.top;

				// 再次检查是否在canvas范围内
				if (offsetX >= 0 && offsetX <= this.mizigeSize && offsetY >= 0 && offsetY <= this.mizigeSize) {
					this.lastX = offsetX;
					this.lastY = offsetY;

					const ctx = this.drawingContexts[index];
					if (ctx) {
						ctx.beginPath();
						ctx.moveTo(offsetX, offsetY);
					}
				} else {
					this.isDrawing = false;
				}

				event.preventDefault();
			},

			draw(index, event) {
				if (!this.isDrawing || index !== this.currentCanvasIndex) return;

				const touch = event.touches ? event.touches[0] : event.changedTouches ? event.changedTouches[0] : event;
				const rect = this.canvasRects[index];

				if (!rect) return;

				const offsetX = touch.clientX - rect.left;
				const offsetY = touch.clientY - rect.top;

				// 限制绘制范围在canvas内部
				if (offsetX >= 0 && offsetX <= this.mizigeSize && offsetY >= 0 && offsetY <= this.mizigeSize) {
					const ctx = this.drawingContexts[index];
					if (ctx) {
						ctx.lineTo(offsetX, offsetY);
						ctx.strokeStyle = 'black';
						ctx.lineWidth = 2;
						ctx.stroke();
						this.lastX = offsetX;
						this.lastY = offsetY;
					}
				} else {
					// 超出范围则停止绘制
					this.stopDrawing(index);
				}

				event.preventDefault();
			},

			stopDrawing(index) {
				this.isDrawing = false;
				this.currentCanvasIndex = -1;
			},

			clearSignature() {
				this.drawingContexts.forEach((ctx, index) => {
					this.drawMizige(ctx);
					this.drawTextMethod(ctx, index);
				});
			},
			// 导出图片
			// exportAsImage() {
			// 	// 先检查合并canvas是否初始化完成
			// 	if (!this.combinedCanvas || !this.combinedCtx) {
			// 		uni.showToast({
			// 			title: '合并画布未就绪，请稍候',
			// 			icon: 'none'
			// 		});
			// 		return;
			// 	}

			// 	// 计算合并后的画布尺寸
			// 	const maxPerLine = 5;
			// 	const lines = Math.ceil(this.mizigeCount / maxPerLine);
			// 	const lineWidth = Math.min(this.mizigeCount, maxPerLine) * this.mizigeSize;
			// 	const totalWidth = lineWidth;
			// 	const totalHeight = lines * this.mizigeSize;

			// 	// 检查所有米字格是否都有签名（
			// 	let allHaveSignature = true;
			// 	const checkPromises = [];
			// 	this.canvasElements.forEach((canvas) => {
			// 		checkPromises.push(new Promise((resolve) => {
			// 			const ctx = canvas.getContext('2d');
			// 			const imageData = ctx.getImageData(0, 0, this.mizigeSize, this.mizigeSize);
			// 			const data = imageData.data;
			// 			let hasSignature = false;
			// 			for (let i = 0; i < data.length; i += 4) {
			// 				if (data[i] === 0 && data[i + 1] === 0 && data[i + 2] === 0 && data[i +
			// 						3] > 0) {
			// 					hasSignature = true;
			// 					break;
			// 				}
			// 			}
			// 			if (!hasSignature) allHaveSignature = false;
			// 			resolve();
			// 		}));
			// 	});

			// 	Promise.all(checkPromises).then(() => {
			// 			// if (!allHaveSignature) {
			// 			//   uni.showToast({ title: '请确保每个米字格都有签名！', icon: 'none' });
			// 			//   return;
			// 			// }

			// 			// 3. 初始化合并Canvas（透明背景）
			// 			this.combinedCanvas.width = totalWidth * this.pixelRatio;
			// 			this.combinedCanvas.height = totalHeight * this.pixelRatio;
			// 			this.combinedCtx.scale(this.pixelRatio, this.pixelRatio);
			// 			// 清除合并Canvas默认背景（设置为透明）
			// 			this.combinedCtx.clearRect(0, 0, totalWidth, totalHeight);

			// 			// 4. 遍历每个原始Canvas，像素级筛选黑色签名并绘制到合并Canvas
			// 			this.canvasElements.forEach((canvas, index) => {
			// 					// 计算当前签名在合并Canvas中的位置（行/列布局）
			// 					const lineIndex = Math.floor(index / maxPerLine);
			// 					const columnIndex = index % maxPerLine;
			// 					const offsetX = columnIndex * this.mizigeSize; // 合并Canvas中的X坐标
			// 					const offsetY = lineIndex * this.mizigeSize; // 合并Canvas中的Y坐标

			// 					// 获取原始Canvas的图像数据（含红色背景+黑色签名）
			// 					const ctx = canvas.getContext('2d');
			// 					const imageData = ctx.getImageData(0, 0, this.mizigeSize, this.mizigeSize);
			// 					const data = imageData.data; // 像素数组：[R0, G0, B0, A0, R1, G1, B1, A1, ...]

			// 					// 创建合并Canvas的图像数据（用于写入黑色签名）
			// 					const combinedImageData = this.combinedCtx.createImageData(this.mizigeSize, this
			// 						.mizigeSize);
			// 					const combinedData = combinedImageData.data;

			// 					// 逐像素筛选：只保留黑色签名（R=0、G=0、B=0且A>0）
			// 					for (let i = 0; i < data.length; i += 4) {
			// 						const r = data[i];
			// 						const g = data[i + 1];
			// 						const b = data[i + 2];
			// 						const a = data[i + 3];

			// 						// 符合黑色签名条件：复制像素到合并数据中；否则设为透明（A=0）
			// 						if (r === 0 && g === 0 && b === 0 && a > 0) {
			// 							//   combinedData[i] = r;     // 红色通道：0（黑色）
			// 							//   combinedData[i + 1] = g; // 绿色通道：0（黑色）
			// 							//   combinedData[i + 2] = b; // 蓝色通道：0（黑色）
			// 							//   combinedData[i + 3] = a; // 透明度：保留原始签名透明度
			// 							// } else {
			// 							//   combinedData[i] = 0;
			// 							//   combinedData[i + 1] = 0;
			// 							//   combinedData[i + 2] = 0;
			// 							//   combinedData[i + 3] = 0; // 透明（A=0），隐藏红色背景
			// 							// }
			// 							combinedData.fillStyle = 'black'
			// 							const pixelx = offsetX + ((i / 4) % this.mizigeSize);
			// 							const pixely = offsetY + Math.floor(i / 4 / this.mizigeSize)
			// 							combinedData.fillRect(pixelx, pixely, 1, 1)
			// 						}

			// 						// 5. 将筛选后的黑色签名绘制到合并Canvas的对应位置
			// 						this.combinedCtx.putImageData(combinedImageData, offsetX, offsetY);
			// 					});

			// 				// 5. 导出合并后的canvas为图片
			// 				uni.canvasToTempFilePath({
			// 					canvas: this.combinedCanvas, // 直接使用提前初始化的合并canvas
			// 					success: (res) => {
			// 						console.log('查看图片', res)
			// 						uni.saveImageToPhotosAlbum({
			// 							filePath: res.tempFilePath,
			// 							success: () => uni.showToast({
			// 								title: '图片保存成功',
			// 								icon: 'success'
			// 							}),
			// 							fail: (err) => {
			// 								console.error('保存失败', err);
			// 								uni.showToast({
			// 									title: '保存失败，请重试',
			// 									icon: 'none'
			// 								});
			// 								if (err.errMsg.includes('auth deny')) {
			// 									uni.openSetting({
			// 										success: (setting) => {
			// 											if (setting.authSetting[
			// 													'scope.writePhotosAlbum'
			// 												]) {
			// 												uni.showToast({
			// 													title: '权限已开启，请重新保存',
			// 													icon: 'none'
			// 												});
			// 											}
			// 										}
			// 									});
			// 								}
			// 							}
			// 						});
			// 					},
			// 					fail: (err) => {
			// 						console.error('转换图片失败', err);
			// 						uni.showToast({
			// 							title: '导出失败，请重试',
			// 							icon: 'none'
			// 						});
			// 					}
			// 				}, this);
			// 			});
			// 	}

			}
		};
</script>

<style scoped>
	.page-container {
		max-width: 100vw;
		max-height: 100vh;
		position: relative;
	}

	.fixed-top {
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
		background-color: white;
		padding: 15px;
		box-sizing: border-box;
		z-index: 1;
	}

	.scrollable-signature {
		margin-top: 220px;
		max-height: calc(100vh - 120px);
		overflow-y: auto;
		padding: 15px;
		box-sizing: border-box;
	}

	.mizige {
		display: inline-block;
		margin: 10px;
		text-align: center;
	}

	/* canvas容器，用于拦截超出范围的事件 */
	.canvas-wrapper {
		display: flex;
		position: relative;

	}

	#mizigeContainer {
		text-align: center;
	}

	::v-deep .van-button {
		margin-bottom: 10px;
	}
</style>